﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Media;

namespace MVVMFramework.View
{
    public sealed class DataGridBehaviour
    {
        public static readonly DependencyProperty DoubleClickCommandProperty = DependencyProperty.RegisterAttached("DoubleClickCommand",
            typeof(ICommand), typeof(DataGridBehaviour), new PropertyMetadata(null, DoubleClickCommandPropertyChanged));

        private static readonly DependencyProperty DoubleClickCommandBehaviourProperty = DependencyProperty.RegisterAttached("DoubleClickCommandBehaviour",
            typeof(DataGridDoubleClickBehaviour), typeof(DataGrid), null);


        public static readonly DependencyProperty EnterCommandProperty = DependencyProperty.RegisterAttached("EnterCommand",
            typeof(ICommand), typeof(DataGridBehaviour), new PropertyMetadata(null, EnterCommandPropertyChanged));

        private static readonly DependencyProperty EnterCommandBehaviourProperty = DependencyProperty.RegisterAttached("EnterCommandBehaviour",
            typeof(DataGridEnterBehaviour), typeof(DataGrid), null);


        public static void SetDoubleClickCommand(DataGrid dataGrid, ICommand command)
        {
            dataGrid.SetValue(DoubleClickCommandProperty, command);
        }

        public static ICommand GetDoubleClickCommand(DataGrid dataGrid)
        {
            return dataGrid.GetValue(DoubleClickCommandProperty) as ICommand;
        }


        public static void SetEnterCommand(DataGrid dataGrid, ICommand command)
        {
            dataGrid.SetValue(EnterCommandProperty, command);
        }

        public static ICommand GetEnterCommand(DataGrid dataGrid)
        {
            return dataGrid.GetValue(EnterCommandProperty) as ICommand;
        }


        private static void DoubleClickCommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid target = d as DataGrid;
            if (target != null)
            {
                DataGridDoubleClickBehaviour behaviour = new DataGridDoubleClickBehaviour(target, e.NewValue as ICommand);
                target.SetValue(DoubleClickCommandBehaviourProperty, behaviour);
            }
        }


        private static void EnterCommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid target = d as DataGrid;
            if (target != null)
            {
                DataGridEnterBehaviour behaviour = new DataGridEnterBehaviour(target, e.NewValue as ICommand);
                target.SetValue(EnterCommandBehaviourProperty, behaviour);
            }
        }

    }

    public class DataGridDoubleClickBehaviour
    {
        private readonly DataGrid _dataGrid;
        private readonly ICommand _command;


        public DataGridDoubleClickBehaviour(DataGrid dataGrid, ICommand command)
        {
            _dataGrid = dataGrid;
            _command = command;

            _dataGrid.MouseDoubleClick += new MouseButtonEventHandler(dataGrid_MouseDoubleClick);
        }

        private void dataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (e.Handled)
                return;

            DataGrid dataGrid = sender as DataGrid;
            if (dataGrid != null)
            {
                UIElement elem = dataGrid.InputHitTest(e.GetPosition(dataGrid)) as UIElement;
                if (elem != null)
                {
                    while (elem != dataGrid)
                    {
                        if (elem is DataGridRow)
                        {
                            // Handle the double click here
                            if (_command != null)
                            {
                                if (_command.CanExecute(null))
                                    _command.Execute(null);

                                e.Handled = true;
                            }
                            return;
                        }
                        elem = VisualTreeHelper.GetParent(elem) as UIElement;

                        if (elem == null)
                            break;
                    }
                }
            }
        }

    }

    public class DataGridEnterBehaviour
    {
        private readonly DataGrid _dataGrid;
        private readonly ICommand _command;

        public DataGridEnterBehaviour(DataGrid dataGrid, ICommand command)
        {
            _dataGrid = dataGrid;
            _command = command;

            _dataGrid.PreviewKeyDown += new KeyEventHandler(_dataGrid_PreviewKeyDown);
        }

        private void _dataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Return)
            {
                DataGrid dataGrid = sender as DataGrid;
                if (dataGrid != null)
                {
                    if (_command != null)
                    {
                        if (_command.CanExecute(null))
                            _command.Execute(null);

                        e.Handled = true;
                    }
                }
            }
        }

    }

}
